package co.uk.j_wp.games.topdowngame;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.IOException;

import javax.swing.JFrame;


import co.uk.j_wp.games.topdowngame.input.KeyMap;
import co.uk.j_wp.games.topdowngame.level.Level;
import co.uk.j_wp.games.topdowngame.level.LevelLoader;
import co.uk.j_wp.games.topdowngame.tile.TileMap;

public class Game extends Canvas implements Runnable {
	private static final long serialVersionUID = -4645858087317011721L;

	// static stuff
	public static final int TILE_SIZE = 16;
	public static final int SCREEN_SIZE_HEIGHT = 10;
	public static final int SCREEN_SIZE_WIDTH = 16;
	public static final int SCREEN_SCALE = 3;
	public static final int SCREEN_OVERALL_HEIGHT = SCREEN_SIZE_HEIGHT * TILE_SIZE;
	public static final int SCREEN_OVERALL_WIDTH = SCREEN_SIZE_WIDTH * TILE_SIZE;

	// screen pizles array
	private BufferedImage image = new BufferedImage(SCREEN_OVERALL_WIDTH, SCREEN_OVERALL_HEIGHT, BufferedImage.TYPE_INT_RGB);
	private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
	private Screen screen = new Screen(pixels);

	public static final String GAME_NAME = "TopDownGame";

	public Game() throws IOException {
		Dimension gameSize = new Dimension(SCREEN_OVERALL_WIDTH * SCREEN_SCALE, SCREEN_OVERALL_HEIGHT * SCREEN_SCALE);
		setPreferredSize(gameSize);
		setMaximumSize(gameSize);
		setMinimumSize(gameSize);

	}

	public static void main(String[] args) throws IOException {
		Game game = new Game();

		JFrame window = new JFrame(GAME_NAME);
		{

			window.setLayout(new BorderLayout());
			window.add(game, BorderLayout.CENTER);
			window.pack();
			window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			window.setLocationRelativeTo(null);
			window.setResizable(false);
			window.setAlwaysOnTop(true);
		}
		window.setVisible(true);

		game.start();
	}

	private Thread t;

	private void start() {

		screen.clearScreen();

		this.addKeyListener(key);

		ticker = new Ticker(this);
		t = new Thread(this);
		t.setName("RENDER THREAD");
		t.start();
	}

	Ticker ticker;
	public TileMap tiles = new TileMap("/tex.png");
	
	//public Level level = new Level(this).levelInitMaze(41, 41);
	//public Level level = new Level(this,new LevelLoader("/map.png", tiles));
	public Level level = new Level(this,new LevelLoader("/Map1.png", tiles));
	//public Level level = new Level(this,new LevelLoader("/JamesMap.png", tiles));

	public void renderCanvas() {
		BufferStrategy bs = getBufferStrategy();
		if (bs == null) {
			createBufferStrategy(3);
			requestFocus();
			return;
		}

		screen.clearScreen();

		level.draw(screen);

		Graphics g = bs.getDrawGraphics();
		g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
		g.dispose();
		bs.show();
	}

	private long nextUpdate = System.currentTimeMillis() + 1000;
	private long FPSCounter = 0;
	private long TICKCounter = 0;
	private long frame = 0;
	private long tick = 0;

	public KeyMap key = new KeyMap();

	@Override
	public void run() {
		while (true) {
			frame++;

			renderCanvas();

			if (nextUpdate < System.currentTimeMillis()) {
				nextUpdate += 1000;
				System.out.println("FPS: " + (frame - FPSCounter) + " TPS: " + (tick - TICKCounter));
				TICKCounter = tick;
				FPSCounter = frame;
			}
		}
	}

	public void tick() {
		tick++;
		level.tick();
	}
}
